package cz.cvut.manatee.client.concordance;

import java.util.ArrayList;
import java.util.LinkedList;

import com.google.gwt.user.client.ui.VerticalPanel;

import cz.cvut.manatee.client.Resources;
import cz.cvut.manatee.shared.AttributItem;
import cz.cvut.manatee.shared.concordance.CollectedParameters;


public class SearchWidgetManagement <T extends ConcordanceFormWidget> implements SearchWidgetManagementInterface<T> {
	private final ArrayList<SearchWidgetWrapper<T>> list;
	private final String        widgetName;
	private final VerticalPanel layout;
	private       int           membersLimit = 0;
	
	
	private LinkedList<FormChangeHandler> changeHadlers;
	
	/**
	 * Instantiates a new search widget management.
	 * 
	 * @param list kolekce ArrayList ve ktere je ulozena polozka "item"
	 * @param item polozka, se kterou budemem manipulovat
	 * @param renderer objekt, ktery umi prekreslit cely formular
	 */
	SearchWidgetManagement(String widgetName) {
		this.widgetName = widgetName;
		this.list       = new ArrayList<SearchWidgetWrapper<T>>();
		this.layout     = new VerticalPanel();
		changeHadlers   = new LinkedList<FormChangeHandler>();
		
		this.layout.addStyleName(Resources.INSTANCE.css().verticalPanel());
	}
	
	
	SearchWidgetManagement(String widgetName, int membersLimit) {
		this(widgetName);
		this.membersLimit = membersLimit;
	}
	
	/**
	 * Posune prvek nahoru
	 * @see cz.cvut.manatee.smartClient.SearchWidgetManagementInterface#moveUp()
	 */
	public void moveUp(SearchWidgetWrapper<T> item) {
		int pos = list.indexOf(item);
		if (pos > 0) {
			list.set(pos, list.get(pos-1));
			list.set(pos-1, item);
			
			//list.get(pos-1).refresh();
			//list.get(pos).refresh();
			this.render();
		}
	}
	
	/**
	 * Posune prvek dolu
	 * @see cz.cvut.manatee.smartClient.SearchWidgetManagementInterface#moveDown()
	 */
	public void moveDown(SearchWidgetWrapper<T> item) {
		int pos = list.indexOf(item);
		if (pos >=0 && pos < list.size()-1 ) {
			list.set(pos, list.get(pos+1));
			list.set(pos+1, item);
			
			//list.get(pos).refresh();
			//list.get(pos+1).refresh();
			this.render();
		}
	}

	/**
	 * Pozice v ArrayList (0 az n-1).
	 */
	public int position(SearchWidgetWrapper<T> item) {
		return list.indexOf(item);
	}
	
	/**
	 * Pocet vsech prvku v ArrayListu.
	 */
	public int size() {
		return this.list.size();
	}
	
	public boolean add(T newitem) {
		if (membersLimit == 0 || (this.list.size() < membersLimit) ) {
			SearchWidgetWrapper<T> wrapper = new SearchWidgetWrapper<T>(newitem, this, this.widgetName);
			list.add(wrapper);
			layout.add(wrapper);
			this.refresh();
			return true;
		}
		
		return false;
	}
	
	public boolean remove(int index) {
		if (index < 0 || index >= list.size()) return false;
		return this.remove(list.get(index));
	}
	
	public boolean remove(SearchWidgetWrapper<T> wrapper) {
		if (list.contains(wrapper)) {
			list.remove(wrapper);
			layout.remove(wrapper);
			this.refresh();
		}
		return false;
	}
	
	/**
	 * Vyprazdni layout a vsechny prvky vlozi znovu
	 */
	public void render() {
		this.layout.clear();
		for (SearchWidgetWrapper<T> item : this.list) {
			this.layout.add(item);
		}
		this.refresh();
	}
	
	/**
	 * Na vsechny prvky v layoutu zavola metodu refresh() - obnovit obsah
	 */
	public void refresh() {
		for (SearchWidgetWrapper<T> item : this.list) {
			item.refresh();
		}
		fireFormChangeEvent("Form refreshed!");
	}
	
	
	public VerticalPanel layout() {
		return this.layout;
	}
	
	
	private void fireFormChangeEvent(String whatHappend) {
		for (FormChangeHandler handler : this.changeHadlers) {
			handler.onFormChange(new FormChangeEvent(whatHappend));
		}
	}
	
	public void addFormChangeHandler(FormChangeHandler handler) {
		this.changeHadlers.add(handler);
	}
	
	public boolean validate() {
		boolean status = true;
		
		for (SearchWidgetWrapper<T> item : list) {
			status = (item.getForm().validate()) && status;
		}
		
		return status;
	}
	
	public void clearError() {
		for (SearchWidgetWrapper<T> item : list) {
			item.getForm().clearError();
		}
	}

	public void setAttributs(AttributItem[] attributs) {
		for(SearchWidgetWrapper<T> wrapper : list){
			wrapper.setAttributs(attributs);
		}
	}

	public CollectedParameters[] getParameters() {
		if(list.size() <= 0) return null;
		CollectedParameters[] paramArray = new CollectedParameters[list.size()];
		int i=0;
		for (SearchWidgetWrapper<T> item : list) {
			paramArray[i++] = item.getParameters();
		}
		return paramArray;
	}

	public void setParameters(CollectedParameters[] params) {
		int i=0;
		for (SearchWidgetWrapper<T> item : list) {
			item.setParameters(params[i++]);
		}
	}

}
